<template>
	<div class="xgrid"  ref="xgridRef">
		<div style="padding-left: 5px;padding-right: 2px;" :style="{width: rightTree? 'calc(100% - 220px)':'100%'}">
			<tiny-grid
				ref="JGridRef"
				show-header-overflow
				highlight-hover-row
				highlight-current-row
				border
				seq-serial
				stripe
				:data="list"
				:size="size"
				footer-cell-class-name="footerCellClassName"
				:edit-config="{ trigger: trigger, mode: 'cell', showStatus: false }"
				:optimization="optimization"
				:cell-class-name="cellClass"
				:height="hei"
				:loading="load.loading"
				:show-footer="showFoot"
				:footer-method="footerMethod"
				:remote-sort="remoteSort"
				:sort-config="{ trigger: 'cell' }"
				:auto-load="false"
        @edit-actived="editActived"
				@edit-closed="editClosed"
				@sort-change="sortChange"
				@cell-click="cellClick"
				@cell-dblclick="cellDblClick"
				@select-all="checkboxAll"
				@select-change="checkboxChange"
			>
        <tiny-grid-column
          v-if="rowOp"
          field="plus"
          align="center"
          :width="70"
        >
          <template #header>
            操作
          </template>
          <template #default="data">
            <div style="display: flex;">
              <IconDel class="icon del" @click="rowDel(data.rowIndex)"></IconDel>
              <IconPlus class="icon add" @click="rowInsert(data.rowIndex)"></IconPlus>
            </div>
          </template>
        </tiny-grid-column>
				<template v-for="(item, index) in columns" :key="index">
					<tiny-grid-column
						v-if="item.title !== '操作'"
						show-overflow="tooltip"
						:type="item.type"
						:width="item.width ? item.width : 0"
						:field="item.field"
						:title="item.title"
						:headerAlign="item.headerAlign ? item.headerAlign : 'center'"
						:align="item.align ? item.align : 'center'"
						:fixed="item.fixed"
						:filter="item.filter"
						:sortable="item.sortable"
						:format-text="formatFn"
						:editor="item.editor?item.editor:null"
					>
					</tiny-grid-column>
					<tiny-grid-column
						:align="item.align ? item.align : 'center'"
						title="操作"
						fixed="right"
						:width="item.width ? item.width : 100"
						headerAlign="center"
						v-else
					>
						<template #default="data">
							<template v-for="(btn, btnIndex) in item.btns" :key="btnIndex">
								<span class="btn" v-if="showBtn(data.row, btn)" @click="rowBtn(btn, data.row)">
									{{ btn.label }}
								</span>
							</template>
						</template>
					</tiny-grid-column>
				</template>
			</tiny-grid>
			<tiny-pager
				v-if="showPage"
				mode="complete"
				:total="total"
				v-model:page-size="pageSize"
				v-model:current-page="currentPage"
				@size-change="sizeChange"
				:page-sizes="pageSizes"
				:pageSize="50"
				@current-change="pageChange"
			></tiny-pager>
		</div>
		<div v-if="rightTree">
			<el-scrollbar :height="gridHeight">
				<tiny-tree
					:data="treeList"
					:expand-on-click-node="false"
					:show-line="true"
					:default-expand-all="true"
					@node-click="handleNodeClick"
				></tiny-tree>
			</el-scrollbar>
		</div>
		<JDialog ref="JEditorRef" />
	</div>
</template>
<script>
import tool from '@/utils/tool';
import JDialog from '@/lui/JEditor.vue';
import { Grid, GridColumn, Pager, Tree } from '@opentiny/vue';
import { IconPlus, IconDel } from '@opentiny/vue-icon'
export default {
	name: 'JGrid',
	components: {
		TinyTree: Tree,
		JDialog,
		TinyGrid: Grid,
		TinyGridColumn: GridColumn,
		TinyPager: Pager,
    IconPlus: IconPlus(),
    IconDel: IconDel(),
	},
	props: {
		trigger: { type: String, default: 'click' }, // 显示表格底部
		rowOp: { type: Boolean, default: false }, // 显示表格底部
		seq: { type: Boolean, default: false }, // 显示表格底部
		card: { type: Boolean, default: true }, // 显示表格底部
		showFooter: { type: Boolean, default: true }, // 显示表格底部
		showPage: { type: Boolean, default: false }, // 显示表格底部
		openPage: { type: Boolean, default: true }, // 是否打开窗口
		showCheckRow: { type: Boolean, default: true }, // 显示复选框列
		showNumRow: { type: Boolean, default: true }, // 显示行号列
		editable: { type: Boolean, default: false },
		dblClickToBill: { type: Boolean, default: false },
		rightTree: { type: Boolean, default: false },
		loading: { type: Boolean, default: false },
		autoLoad: { type: Boolean, default: true }, // 显示表格底部
		clickRowToSelect: { type: Boolean, default: false }, // 显示表格底部
		isTree: { type: Boolean, default: false }, // 树形表格
		remoteSort: { type: Boolean, default: true }, // 树形表格
		dbClickEdit: { type: Boolean, default: false }, // 双击编辑
		detail: { type: Boolean, default: false }, // 取明细表列配置
		fileName: { type: String, default: '' }, // 下载的文件名
		gridHeight: { type: [Number, String], default: 0 }, // 下载的文件名
		gridWidth: { type: Number, default: 0 }, // 下载的文件名
		offsetHeight: { type: [Number, String], default: 0 }, // 减去高度
		size: { type: String, default: 'small' }, //
		whichPage: { type: String, default: '' }, //
		header: { type: String, default: '' }, //
		listUrl: { type: String, default: '' }, //
		top: { type: Number, default: 0 }, //
		contextmenu: {
			type: Array,
			default: function () {
				return [];
			},
		}, // 表格右键菜单
		fields: {
			type: Array,
			default: function () {
				return [];
			},
		},
		dataList: {
			type: Array,
			default: function () {
				return [];
			},
		},
		searchModel: {
			type: Object,
			default: function () {
				return {};
			},
		}, // 搜索条件
	},
	data() {
		return {
			url: '',
			fieldObj: {},
			pageSize: 50,
			currentPage: 1,
			list: [],
      doevent: {
        blur () {
        }
      },
			total: 0,
			fApi: null,
			columns: [],
			hei: this.gridHeight,
			load: {
				loading: false,
			},
			filterOpen: false,
			hideFooter: false,
			hidePage: false,
			query: {},
			filter: {
				multi: true,
				enumable: true,
				defaultFilter: true,
				inputFilter: true,
			},
			timeval: 0,
			excel: 0,
			optimization: {
				animat: false,
				delayHover: 1000,
			},
			sortArr: {}, // {}
      treeList: [],
      goodCatCode: '',
      columnIndex: 0,
      rowIndex: 0,
      currentRow: {},
      currentColumn: {}
		};
	},
	emits: ['rowBtn', 'mounted', 'cellClick', 'cellDblClick','editActived', 'editClosed', 'changePage','rowDel','rowInsert'],
	methods: {
    setColumns (cols) {
      // this.columns = cols
      this.$refs.JGridRef.loadColumn(cols)
    },
    rowDel (index) {
      this.$emit('rowDel', index)
    },
    rowInsert (index) {
      this.$emit('rowInsert', index)
    },
    getRightTreeList () {
      if(this.rightTree) {
        tool.post('dropdown/goodCatList').then(ret => {
          let list = [
            {id: 0,label:'全部', children: tool.toArrayTree(ret.data)}
          ]
          this.treeList = list
        })
      }
    },
    handleNodeClick (data) {
      this.goodCatCode = data.code?data.code:''
      this.$nextTick(() => {
        this.getList()
      })
    },
		formatFn(cell) {
			let formatter = this.colObject[cell.column.property].formatter;
			if (formatter === 'formatMoney') {
				return tool.xe.toNumber(cell.cellValue) ? tool.xe.toFixed(cell.cellValue, 2) : '';
			}
			if (formatter === 'formatQty' || formatter === 'formatZero') {
				return tool.xe.toNumber(cell.cellValue) ? tool.xe.toNumber(cell.cellValue) : '';
			}
			return cell.cellValue;
		},
		setApi(api) {
			this.fApi = api;
		},
		openEdit(pars) {
			this.$refs.JEditorRef.open({ title: pars.title, params: pars });
		},
		getList(excel = 0) {
			if (!this.url) return;
			let search = {
        goodCatCode: this.goodCatCode,
				...this.query,
			};
			if (this.fApi) {
				if (this.fApi.getValue('search')) {
					search = Object.assign(search, this.fApi.getValue('search'));
				}
				if (this.fApi.getValue('toolbar')) {
					search = Object.assign(search, this.fApi.getValue('toolbar'));
				}
			} else {
				search = Object.assign(search, this.searchModel);
			}
			let params = {
				excel,
				whichPage: this.whichPage,
				currentPage: this.currentPage,
				pageSize: this.pageSize,
				formData: search,
				sort: this.getSort(),
			};
			this.load.loading = true;
			tool.post(this.url, params, this.load).then((ret) => {
				if (ret.stat) {
					if (excel && ret.data) {
						window.open(ret.data, '_blank');
					} else {
						this.total = ret.data.total;
						if (this.fApi) {
							if (this.fApi.getValue('toolbar')) {
								this.fApi.exec('toolbar', 'updateTotal', this.total);
							}
						}
						// ret.data.list.map((row) => {
						//   row.checked = false;
						// });
						if (ret.data.columns) {
							this.setGridColumn(ret.data.columns, true);
						}
            this.setData(ret.data.total, ret.data.list)
						// this.list = ret.data.list;
						// this.$refs.JGridRef.loadData(ret.data.list);
						// this.updateFooter();
					}
				}
			});
		},
    setData(total, data) {
      this.total = total;
      this.list = data;

      // this.$refs.JGridRef.loadData(data);
      // if(data.length > 0)
      // {
      //   setTimeout(() => {
      //     // this.$refs.JGridRef.scrollToRow(data[0]);
      //     this.$refs.JGridRef.recalculate()
      //   }, 3000)
      // }
      this.updateFooter();
    },
		rowBtn(btn, row) {
			if (typeof btn.click === 'function') {
				btn.click(row);
			} else {
				this.$emit('rowBtn', btn, row);
			}
		},
		sizeChange() {
			this.currentPage = 1;
			this.pageChange();
		},
		pageChange() {
			this.$emit('changePage', { pageSize: this.pageSize, currentPage: this.currentPage });
		},
		setGridColumn(columns, remote = false) {
			let col = [];
			columns.map((row) => {
				row.type = row.type === 'seq' ? 'index' : row.type === 'checkbox' ? 'selection' : '';
				row.headerAlign = row.headerAlign ? row.headerAlign : 'center';
				row.align = row.align ? row.align : 'left';
				row.width = row.width ? row.width : 100;
				if (typeof row.filter === 'boolean' && row.filter) {
					row.filter = this.filter;
				} else {
					delete row.filter;
				}
				delete row.filters;
				delete row.filterRender;
				delete row.slots;
				if (row.type === 'index') {
					col.push(row);
				}
				if (row.type === 'selection') {
					row.field = 'checked';
					col.push(row);
				}
				if (row.title === '操作') {
					col.push(row);
				}
				if (row.visible) col.push(row);
			});
			//
			if (remote) {
				//
				this.$nextTick(() => {
					setTimeout(() => {
						this.$refs.JGridRef.loadColumn(col);
						this.columns = col;
					}, 20);
				});
			} else {
				this.columns = col;
			}
		},
		// 设置表格高度
		setGridHeight() {
			if (!this.gridHeight) {
				setTimeout(() => {
					let rect = this.$refs.xgridRef.getBoundingClientRect();
					let h = tool.xe.toInteger(window.innerHeight - rect.top) - 0;
					if (this.offsetHeight) {
						if (typeof this.offsetHeight === 'string') {
							h = tool.multiply(h, this.offsetHeight);
						}
						if (typeof this.offsetHeight === 'number') {
							h = h - this.offsetHeight;
						}
					}
					this.hei = h - (this.showPage ? 60 : 0);
					this.$emit('mounted');
				}, 300);
			}
		},
		// 设置列
		getGridColumns() {
			if (this.columns.length === 0) {
				tool.post('page/getGridColumns', { whichPage: this.whichPage, detail: this.detail }).then((ret) => {
					if (ret.stat) {
						this.hideFooter = ret.data.hideFooter;
						this.hidePage = ret.data.hidePage;
						if (this.detail) {
							this.columns = ret.data.detailGrid;
						} else {
							let columns = new Function('_this', '_tool', 'return' + ret.data.fields)(this, tool);
							this.setGridColumn(columns);
							if (ret.data.listUrl) {
								this.url = ret.data.listUrl ? ret.data.listUrl : 'list/bill';
								setTimeout(() => {
									this.getList();
								}, 300);
							}
						}
					}
				});
			} else {
				if (this.listUrl) {
					this.url = this.listUrl;
					this.getList();
				}
			}
		},
		showBtn(row, btn) {
			if (typeof btn.show === 'undefined') return true;
			return new Function('row', 'return ' + btn.show)(row);
		},
		search() {
			this.currentPage = 1;
			this.getList();
		},
		// 工具栏分页
		toobarPageChange({ currentPage, pageSize }) {
			this.currentPage = currentPage;
			this.pageSize = pageSize;
			this.getList();
		},
		clearFilter() {
			this.$refs.JGridRef.clearFilter();
		},
		setActiveCell(row, field) {
			this.$refs.JGridRef.setActiveCell(row, field);
		},
		getSort() {
			if (!this.remoteSort) return;
			let list = [];
			if (!tool.xe.isEmpty(this.sortArr)) {
				for (let i in this.sortArr) {
					list.push({
						field: i,
						order: this.sortArr[i],
					});
				}
			}
			return list;
		},
    editActived (cell) {
      this.$emit('editActived', cell)
    },
		editClosed(cell) {
			this.$emit('editClosed', cell);
		},
		refresh() {
			this.currentPage = 1;
			this.$refs.JGridRef.clearSort();
			this.$refs.JGridRef.clearFilter();
			this.sortArr = {};
			this.getList();
		},
		sortChange({ field, order }) {
			if (!this.remoteSort) return;
			if (order) {
				this.sortArr[field] = order;
			} else {
				delete this.sortArr[field];
			}
			this.getList();
		},
		checkboxChange() {
			this.updateFooter();
		},
		// 全选
		checkboxAll() {
			this.updateFooter();
		},
		rowClassName({ row }) {
			let css = '';
			if (row.billType === '小计' || row.amount === '小计') {
				css += 'row-green';
			}
			if (row.transTypeName && row.transTypeName === '小计') {
				css += ' subTotal ';
			}
			return css;
		},
		getOffset() {
			return this.$refs.xgridRef.getBoundingClientRect();
		},
		updateFooter() {
			this.$refs.JGridRef.updateFooter();
		},
		// 底部汇总
		footerMethod({ columns, data }) {
			let ret = [];
			let list = this.$refs.JGridRef.getSelectRecords();
			if (list.length === 0) list = data;

			let cols = [];
			this.columns.map((row) => {
				if (row.children) {
					row.children.map((col) => {
						cols.push(col);
					});
				} else {
					cols.push(row);
				}
			});
			ret = columns.map((column) => {
        let field = column.property
				let col = {};
				for (let i = 0; i < cols.length; i++) {
					if (cols[i].field === field) {
						col = cols[i];
					}
				}
				if (col.sum) {
					let s = tool.xe.sum(list, field);
					if (s) {
						if (column.formatter === 'formatMoney') {
							s = s ? tool.xe.toFixed(s, 2) : '';
						}
						return s ? tool.xe.toFixed(s, 2) : '';
					} else {
						return '';
					}
				}
				if (typeof col.sumIsLast !== 'undefined' && col.sumIsLast) {
					if (data.length - 1 >= 0) return tool.xe.toFixed(data[data.length - 1][field], 2);
				}
				if (typeof col.subSum !== 'undefined' && col.subSum) {
					let subList = list.filter((row) => {
						return row.transTypeName === '小计';
					});
					let s = tool.xe.sum(subList, field);
					if (s) {
						if (column.formatter === 'formatMoney') {
							s = s ? tool.xe.toFixed(s, 2) : '';
						}
						return s ? tool.xe.toFixed(s, 2) : '';
					} else {
						return '';
					}
				}
				return '';
			});
			return [ret];
		},
		// 返回选中行
		getSelected() {
			return this.$refs.JGridRef.getSelectRecords();
		},
		// 从列表中删除已选中的行
		removeSelecteds() {
			this.$refs.JGridRef.removeSelecteds();
		},
		// cell样式名
		cellClass({ row, column }) {

			let field = column.property;
			let css = ' ';
			if (field && field === 'billStateName') {
				if (row.billState) css += ' billState-' + row.billState;
			}
			if (field && field === 'seq') {
				css += ' seq ';
			}
			if (
				field &&
				typeof this.colObject[field] !== 'undefined' &&
				typeof this.colObject[field].canClick !== 'undefined' &&
				this.colObject[field].canClick
			) {
				css += ' canClick ';
			}
			if (row[field] === '小计') {
				css += ' subTotal ';
			}
			if (row.transTypeName && row.transTypeName === '小计') css += ' subTotal ';
			return css;
		},
		// 双击单元格
		cellDblClick({ row, column }) {
			if (this.dbClickEdit) {
				if (this.columns && this.columns.length > 0) {
					let opCol = this.columns[this.columns.length - 1];
					if (opCol.btns && opCol.btns.length > 0) {
						for (let i = 0; i < opCol.btns.length; i++) {
							if (opCol.btns[i].label === '编辑') {
								if (typeof opCol.btns[i].click === 'function') opCol.btns[i].click(row);
								break;
							}
						}
					}
				}
			}
			// 双击行跳转到开票
			if (this.dblClickToBill) {
				if (typeof this.colObject.billNo !== 'undefined' && this.colObject.billNo.canClick) {
					tool.openPage(row, 'billNo', this.$route, this.$router);
				}
			}
			this.$emit('cellDblClick', { row, column });
		},
		// 单击单元格
		cellClick({ row, column,rowIndex, columnIndex }) {
      this.currentRow = row
      this.currentColumn = column
      this.rowIndex = rowIndex
      this.columnIndex = columnIndex
			let field = column.property;
			let cols = this.columns.filter((row) => {
				return field === row.field;
			});
			if (this.clickRowToSelect) {
				if (!this.colObject[field].editor && !this.colObject[field].canClick) {
					this.$refs.JGridRef.toggleRowSelection(row);
					this.updateFooter();
				}
			}
			if (cols.length === 1) {
				let col = cols[0];
				if (row[field] === '小计') return;
				if (row[field] && col.canClick) {
					tool.openPage(row, field, this.$route, this.$router);
				}
			}
      this.$emit('cellClick', { row, column });
		},
		// 打印当前页面
		toPrint() {
			this.$refs.JGridRef.openPrint({ sheetName: this.fileName });
		},
		download() {
			this.$refs.JGridRef.exportCsv({
				filename: '导出文件.csv',
				original: true,
				isHeader: true,
				data: this.tableData,
			});
			// this.$refs.JGridRef.openExport();
		},
	},
	created() {
		if (this.$route.query && !tool.xe.isEmpty(this.$route.query)) {
			let que = this.$route.query;
			delete que.m;
			this.query = que;
			if (!tool.xe.isEmpty(que)) {
				// setTimeout(() => {
				//   this.fApi.exec('search', 'setData', que)
				//   // this.query = {}
				// }, 200)
			}
		}
		this.hei = this.gridHeight ? this.gridHeight : 300;
		if (this.listUrl) this.url = this.listUrl;
		if (this.fields && this.fields.length > 0) {
			this.columns = this.fields;
		}
		if (this.dataList && this.dataList.length > 0) {
			this.list = this.dataList;
		}

		if (this.whichPage) {
			this.getGridColumns();
		}
		window.addEventListener('resize', this.setGridHeight);
    this.getRightTreeList()
	},
	activated() {
		// this.getList();
		window.addEventListener('resize', this.setGridHeight);
	},
	deactivated() {
		window.removeEventListener('resize', this.setGridHeight);
	},
	computed: {
		showFoot() {
			return this.showFooter && !this.hideFooter;
		},
		// 显示页码
		sp() {
			return this.showPage && !this.hidePage;
		},
		layout() {
			return ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total'];
		},
		// 右键菜单
		tableMenu() {
			let menu = {
				header: {
					options: [
						[
							{ code: 'hideColumn', name: '隐藏列', disabled: false },
							{ code: 'showAllColumn', name: '取消所有隐藏列', disabled: false },
						],
					],
				},
				body: {
					options: [this.contextmenu],
				},
			};
			if (this.contextmenu.length === 0) return {};
			return menu;
		},
		// 选中行
		checkedRows() {
			return this.list.filter((row) => {
				return row.checked;
			});
		},
		treeConfig() {
			return this.isTree ? { children: 'children', expandAll: false } : null;
		},
		tbId() {
			return 'JGrid' + Date.now();
		},
		colObject() {
			let obj = {};
			for (let i = 0; i < this.columns.length; i++) {
				obj[this.columns[i].field] = this.columns[i];
			}
			return obj;
		},
		pageSizes() {
			return [50, 100, 500];
		},
		lists: {
			get() {
				return this.list;
			},
			set() {},
		},
	},
	watch: {
		dataList: {
			handler: function (val) {
				this.list = val;
			},
			deep: true,
		},
		fields: {
			deep: true,
			handler: function (val) {
				this.columns = val;
			},
		},
	},
	mounted() {
		this.setGridHeight();
	},
};
</script>

<style  scoped lang="scss">
:deep(.tiny-grid__body-wrapper) {
  background-color: rgba(0,0,0,0.04);
}
:deep(.tiny-grid__body-wrapper::-webkit-scrollbar) {
  height: 10px;
}
:deep(.tiny-grid-body__column .tiny-grid-cell) {
  color: #2b2b2b;
  font-size: 14px;
}

.icon {
  margin-right: 10px;
  font-size: 1.2em;
  fill: #8994aa;
  &:hover {
    cursor: pointer;
  }
}
.add {
  &:hover {
    fill: #1e9fff;
  }
}
.del {
  color: #ED5565;
  &:hover {
    fill: red;
  }
}
.xgrid {
	width: 100%;
	box-sizing: border-box;
	background-color: white;
	display: flex;
}
.btn {
	color: #01aaee;
	font-size: 12px;
	margin-right: 8px;
  user-select: none;
}
.btn {
	&:hover {
		cursor: pointer;
		color: #2b85e4;
	}
}
:deep(.subTotal) {
	font-weight: bold;
	background-color: #edfff9;
	color: #1e9fff;
	font-size: 13px;
}

:deep(.tiny-grid-cell) {
	padding:0 2px !important;
}
:deep(.billState-draft) {
  .tiny-grid-cell {
    color: mediumseagreen;
  }
}

:deep(.billState-del) {
  .tiny-grid-cell {
    color: #bdbdbd;
  }
}

:deep(.footerCellClassName) {
	font-size: 14px;
	height: 35px;
	padding: 0 !important;
	color: #f56c6c;
}
:deep(.canClick) {
  .tiny-grid-cell {
    color: dodgerblue;
  }
	cursor: pointer;
	&:hover {
		text-decoration: underline;
	}
}
</style>